"""
模型数据模型
"""
from datetime import datetime
from typing import Optional
from sqlalchemy import (
    Column, Integer, String, Boolean, DateTime, Text, 
    JSON, ForeignKey, Float, Enum as SQLEnum
)
from sqlalchemy.orm import relationship
from sqlalchemy.sql import func
import enum

from app.core.database import Base


class ModelStatus(str, enum.Enum):
    """模型状态枚举"""
    TRAINING = "training"
    TRAINED = "trained"
    VALIDATED = "validated"
    DEPLOYED = "deployed"
    ARCHIVED = "archived"
    FAILED = "failed"


class ModelFormat(str, enum.Enum):
    """模型格式枚举"""
    PYTORCH = "pytorch"
    ONNX = "onnx"
    TENSORRT = "tensorrt"
    TENSORFLOW = "tensorflow"
    HUGGINGFACE = "huggingface"


class DeploymentStatus(str, enum.Enum):
    """部署状态枚举"""
    NOT_DEPLOYED = "not_deployed"
    DEPLOYING = "deploying"
    DEPLOYED = "deployed"
    DEPLOYMENT_FAILED = "deployment_failed"
    SCALING = "scaling"
    STOPPED = "stopped"


class Model(Base):
    """模型模型"""
    __tablename__ = "models"
    
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), nullable=False, index=True)
    version = Column(String(20), nullable=False)
    description = Column(Text, nullable=True)
    status = Column(SQLEnum(ModelStatus), default=ModelStatus.TRAINING, nullable=False)
    
    # 模型基本信息
    model_type = Column(String(50), nullable=False)  # transformer, cnn, rnn等
    model_format = Column(SQLEnum(ModelFormat), default=ModelFormat.PYTORCH, nullable=False)
    model_size_mb = Column(Float, nullable=True)
    parameter_count = Column(Integer, nullable=True)
    
    # 模型路径和存储
    model_path = Column(String(500), nullable=True)  # 模型文件路径
    checkpoint_path = Column(String(500), nullable=True)  # 检查点路径
    config_path = Column(String(500), nullable=True)  # 配置文件路径
    metadata_path = Column(String(500), nullable=True)  # 元数据路径
    
    # 模型配置
    model_config = Column(JSON, default=dict, nullable=False)
    input_schema = Column(JSON, default=dict, nullable=False)  # 输入格式定义
    output_schema = Column(JSON, default=dict, nullable=False)  # 输出格式定义
    preprocessing_config = Column(JSON, default=dict, nullable=False)
    
    # 性能指标
    training_metrics = Column(JSON, default=dict, nullable=False)
    validation_metrics = Column(JSON, default=dict, nullable=False)
    test_metrics = Column(JSON, default=dict, nullable=False)
    inference_time_ms = Column(Float, nullable=True)  # 推理时间(毫秒)
    throughput_qps = Column(Float, nullable=True)  # 吞吐量(QPS)
    
    # 部署信息
    deployment_status = Column(SQLEnum(DeploymentStatus), default=DeploymentStatus.NOT_DEPLOYED, nullable=False)
    deployment_config = Column(JSON, default=dict, nullable=False)
    endpoint_url = Column(String(255), nullable=True)
    deployment_instances = Column(Integer, default=0, nullable=False)
    
    # 版本和血缘
    parent_model_id = Column(Integer, ForeignKey("models.id"), nullable=True)
    base_model_name = Column(String(100), nullable=True)  # 基础模型名称(如GPT-3.5)
    is_fine_tuned = Column(Boolean, default=False, nullable=False)
    
    # 使用统计
    inference_count = Column(Integer, default=0, nullable=False)
    last_inference_at = Column(DateTime(timezone=True), nullable=True)
    download_count = Column(Integer, default=0, nullable=False)
    
    # 质量评分
    quality_score = Column(Float, nullable=True)  # 0-100
    model_tags = Column(JSON, default=list, nullable=False)
    
    # 关联关系
    project_id = Column(Integer, ForeignKey("projects.id"), nullable=False)
    training_job_id = Column(Integer, ForeignKey("training_jobs.id"), nullable=True)
    created_by = Column(Integer, ForeignKey("users.id"), nullable=False)
    
    # 时间戳
    trained_at = Column(DateTime(timezone=True), nullable=True)
    deployed_at = Column(DateTime(timezone=True), nullable=True)
    created_at = Column(DateTime(timezone=True), server_default=func.now(), nullable=False)
    updated_at = Column(DateTime(timezone=True), server_default=func.now(), onupdate=func.now(), nullable=False)
    
    # 关系
    project = relationship("Project", back_populates="models")
    training_job = relationship("TrainingJob", back_populates="models")
    creator = relationship("User", foreign_keys=[created_by])
    parent_model = relationship("Model", remote_side=[id])
    child_models = relationship("Model", remote_side=[parent_model_id])
    
    def __repr__(self):
        return f"<Model(id={self.id}, name='{self.name}', version='{self.version}')>"
    
    @property
    def full_name(self) -> str:
        """完整模型名称"""
        return f"{self.name}:{self.version}"